#include "RN.h"

RN::RN()
{
    Raiz = NULL;
}


void RN::Insertar(int clave, int Num_Tarjeta, int Cod_Banco, int Monto, std::string CoD)
{
    Tarjeta temp;
    temp.Num_Tarjeta = Num_Tarjeta;
    temp.Cod_Banco = Cod_Banco;
    temp.Monto = Monto;
    temp.CoD = CoD;
    Insertar(clave,temp);
    VIFS::V_WriteLog("RN: insercion");
}
/*
void RN::Insertar(int clave, Tarjeta Datos)                //NodoArbol<Tarjeta> *inicio; ---> el inicio del arbol
{

    int ladohijo;
    NodoArbol<Tarjeta> *hijo;
    NodoArbol<Tarjeta> *ayudante;
    int bandera;

    if (!Raiz){                            //(!inicio){ // el arbol esta vacio cargando como raiz
         Raiz = new NodoArbol<Tarjeta>(clave,Datos);                                    // inicio = new NodoArbol<Tarjeta>(clave,Datos);
        //inicio->llave=key; strcpy(inicio->cadena,cad); inicio->padre=NULL;    //agregar al nodo un campo que se llame Padre
        //inicio->izquierdo=NULL; inicio->derecho=NULL; inicio->color='n';
      }
      else{ // el arbol no esta vacio buscando su lugar
        hijo = new NodoArbol<Tarjeta>(clave,Datos,3);
        ayudante = Raiz;                  //ayudante=inicio;
        do{
          hijo->setPadre(ayudante);
          bandera=1;
          if(clave < ayudante->getClave()){
              if(ayudante->getHizq())   //original: if(ayudante->izquierdo)   , pregunta que si no es NULL??
                ayudante = ayudante->getHizq();
              else
                ayudante->setHizq(hijo);
                bandera = 0;
                ladohijo = 1;

          }else{
              if(ayudante->getHder())
                  ayudante = ayudante->getHder();
              else
                  ayudante->setHder(hijo);
                  bandera=0;
                  ladohijo=2;
          }
        }while(bandera==1);
        if(ayudante->getRojicidad() == true)
            SolucionarRojoRojo(ayudante, ladohijo);
      }
}


void RN::SolucionarRojoRojo(NodoArbol<Tarjeta> *nodo, int h)
{
    int ladohijo;
    NodoArbol<Tarjeta> *abuelo; // en node traemos al padre, en h 1 si el hijo rojo es el izquierdo 2 si no
    NodoArbol<Tarjeta> *tio;
    NodoArbol<Tarjeta> *ayudante;
    abuelo = nodo->getPadre();
    if (abuelo->getHizq() && abuelo->getHder()){
        if (nodo == abuelo->getHizq())
            tio = abuelo->getHder();
        else tio=abuelo->getHizq();

        if(tio->getRojicidad() == true){    //casos 1 y 2
            tio->setRojicidad(false);
            nodo->setRojicidad(false);
            if(abuelo != Raiz)       //original:    if(abuelo != inicio)
                abuelo->setRojicidad(true);
            if(abuelo->getPadre()){
                ayudante = abuelo->getPadre();
                if(ayudante->getHizq() == abuelo)
                    ladohijo=1;
                else
                    ladohijo = 2;
            if(ayudante->getRojicidad() == true)
                SolucionarRojoRojo(ayudante, ladohijo);

          }
          return;
        }
   }


    if(h == 1 && abuelo->getHizq() == nodo){ //caso 3
        nodo->setRojicidad(false);
        abuelo->setRojicidad(true);
        ayudante=nodo->getHder();
        nodo->setHder(abuelo);
        nodo->setPadre(abuelo->getPadre());
        abuelo->setPadre(nodo);
        abuelo->setHizq(ayudante);

        if (ayudante)
            ayudante->setPadre(abuelo);
        if (nodo->getPadre()){
            ayudante= nodo->getPadre();
        if(ayudante->getHizq() == nodo->getHder())
                ayudante->setHizq(nodo);
        else
            ayudante->setHder(nodo);
        }
        else Raiz=nodo;    //original else inicio=nodo;
      }


    else if(h == 2 && abuelo->getHder() == nodo){ //caso 4
        nodo->setRojicidad(false);
        abuelo->setRojicidad(true);
        ayudante=nodo->getHizq();
        nodo->setHizq(abuelo);
        nodo->setPadre(abuelo->getPadre());
        abuelo->setPadre(nodo);
        abuelo->setHder(ayudante);

        if (ayudante)
            ayudante->setPadre(abuelo);
        if (nodo->getPadre()){
            ayudante= nodo->getPadre();
        if(ayudante->getHizq() == nodo->getHizq())
            ayudante->setHizq(nodo);
        else
            ayudante->setHder(nodo);
        }
        else Raiz=nodo;    //original else inicio=nodo;
    }



    else if(h == 2 && abuelo->getHizq() == nodo){ //caso 5
        tio = nodo->getHder();
        ayudante = tio->getHizq();
        abuelo->setHizq(tio);
        tio->setPadre(abuelo);
        tio->setHizq(nodo);
        nodo->setPadre(tio);
        nodo->setHder(ayudante);
        if (ayudante)
            ayudante->setPadre(nodo);
        SolucionarRojoRojo(tio, 1);
      }



    else if(h == 1 && abuelo->getHder() == nodo){ //caso 6
        tio = nodo->getHizq();
        ayudante = tio->getHder();
        abuelo->setHder(tio);

        tio->setPadre(abuelo);
        tio->setHder(nodo);
        nodo->setPadre(tio);

        nodo->setHizq(ayudante);

        if (ayudante)
            ayudante->setPadre(nodo);
        SolucionarRojoRojo(tio, 2);
      }
}

*/
void RN::Insertar(int clave, Tarjeta Datos)
{
    if (Vacio())
        Raiz=new NodoArbol<Tarjeta>(clave,Datos);
    else if(Raiz->getClave()>clave)
    {
        if(Raiz->getHizq())
            Insertar(clave, Datos,Raiz->getHizq(),&Raiz);
        else
            Raiz->setHizq(new NodoArbol<Tarjeta>(clave,Datos,3));
    }
    else
    {
        if(Raiz->getHder())
            Insertar(clave, Datos,Raiz->getHder(),&Raiz);
        else
            Raiz->setHder(new NodoArbol<Tarjeta>(clave,Datos,3));
    }
    Raiz->setRojicidad(false);
}

void RN::Insertar(int clave, Tarjeta Datos, NodoArbol<Tarjeta> *raiz, NodoArbol<Tarjeta> **padre)
{
    if(raiz->getClave()>=clave)
    {
        if(raiz->getHizq())
        {
            if(raiz->getClave()<(*padre)->getClave())
                Insertar(clave, Datos,raiz->getHizq(),(*padre)->getHHizq());
            else
                Insertar(clave, Datos,raiz->getHizq(),(*padre)->getHHder());
        }
        else
            raiz->setHizq(new NodoArbol<Tarjeta>(clave,Datos,3));
        if(raiz->getClave()<(*padre)->getClave())
            raiz=(*padre)->getHizq();
        else
            raiz=(*padre)->getHder();
        if(raiz->getRojicidad()&& raiz->getHizq()->getRojicidad())
        {
            if((*padre)->getClave()>=clave)
            {
                if((*padre)->getHder())
                    if((*padre)->getHder()->getRojicidad())
                    {
                        //Tio #1
                        VIFS::V_WriteLog("RN: Tio");
                        raiz->setRojicidad(false);
                        (*padre)->setRojicidad(true);
                        (*padre)->getHder()->setRojicidad(false);
                    }
                    else
                    {
                        //Rotacion simple #1
                        VIFS::V_WriteLog("RN: RSI");
                        (*padre)->setRojicidad(true);
                        raiz->setRojicidad(false);
                        (*padre)->setHizq(raiz->getHder());
                        raiz->setHder(*padre);
                        (*padre)=raiz;
                    }
                else
                {
                    //Rotacion simple #1
                    VIFS::V_WriteLog("RN: RSI");
                    (*padre)->setRojicidad(true);
                    raiz->setRojicidad(false);
                    (*padre)->setHizq(raiz->getHder());
                    raiz->setHder(*padre);
                    (*padre)=raiz;
                }
            }
            else
            {
                if((*padre)->getHizq())
                    if((*padre)->getHizq()->getRojicidad())
                    {
                        //Tio #2
                        VIFS::V_WriteLog("RN: Tio");
                        raiz->setRojicidad(false);
                        (*padre)->setRojicidad(true);
                        (*padre)->getHizq()->setRojicidad(false);
                    }
                    else
                    {
                        //rotacion Doble #1
                        VIFS::V_WriteLog("RN: RDI");
                        NodoArbol<Tarjeta>* Temp = raiz->getHizq();
                        (*padre)->setRojicidad(true);
                        Temp->setRojicidad(false);
                        (*padre)->setHder(Temp->getHizq());
                        raiz->setHizq(Temp->getHder());
                        Temp->setHder(raiz);
                        Temp->setHizq(*padre);
                        *padre=Temp;
                    }
                else
                {
                    //rotacion Doble #2
                    VIFS::V_WriteLog("RN: RDI");
                    NodoArbol<Tarjeta>* Temp = raiz->getHizq();
                    (*padre)->setRojicidad(true);
                    Temp->setRojicidad(false);
                    (*padre)->setHder(Temp->getHizq());
                    raiz->setHizq(Temp->getHder());
                    Temp->setHder(raiz);
                    Temp->setHizq(*padre);
                    *padre=Temp;
                }

            }
        }
    }
    else
    {
        if(raiz->getHder())
        {
            if(raiz->getClave()<(*padre)->getClave())
                Insertar(clave, Datos,raiz->getHder(),(*padre)->getHHizq());
            else
                Insertar(clave, Datos,raiz->getHder(),(*padre)->getHHder());
        }
        else
            raiz->setHder(new NodoArbol<Tarjeta>(clave,Datos,3));
        if(raiz->getClave()<(*padre)->getClave())
            raiz=(*padre)->getHizq();
        else
            raiz=(*padre)->getHder();

        if(raiz->getRojicidad()&& raiz->getHder()->getRojicidad())
        {
            if ((*padre)->getClave()<raiz->getClave())
            {
                if((*padre)->getHizq())
                    if((*padre)->getHizq()->getRojicidad())
                    {
                        //Tio # 3
                        VIFS::V_WriteLog("RN: Tio");
                        raiz->setRojicidad(false);
                        (*padre)->setRojicidad(true);
                        (*padre)->getHizq()->setRojicidad(false);
                    }
                    else
                    {
                        //Rotacion simple #2
                        VIFS::V_WriteLog("RN: RSD");
                        (*padre)->setRojicidad(true);
                        raiz->setRojicidad(false);
                        (*padre)->setHder(raiz->getHizq());
                        raiz->setHizq(*padre);
                        (*padre)=raiz;
                    }
                else
                {
                    //Rotacion simple #2
                    VIFS::V_WriteLog("RN: RSI");
                    (*padre)->setRojicidad(true);
                    raiz->setRojicidad(false);
                    (*padre)->setHder(raiz->getHizq());
                    raiz->setHizq(*padre);
                    (*padre)=raiz;
                }
            }
            else
            {
                if((*padre)->getHder())
                    if((*padre)->getHder()->getRojicidad())
                    {
                        //Tio #4
                        VIFS::V_WriteLog("RN: Tio");
                        raiz->setRojicidad(false);
                        (*padre)->setRojicidad(true);
                        (*padre)->getHder()->setRojicidad(false);
                    }
                    else
                    {
                        //rotacion Doble #2
                        VIFS::V_WriteLog("RN: RDD");
                        NodoArbol<Tarjeta>* Temp = raiz->getHder();
                        (*padre)->setRojicidad(true);
                        Temp->setRojicidad(false);
                        (*padre)->setHizq(Temp->getHder());
                        raiz->setHizq(Temp->getHizq());
                        Temp->setHizq(raiz);
                        Temp->setHder(*padre);
                        *padre=Temp;
                    }
                else
                {
                    //rotacion Doble
                    VIFS::V_WriteLog("RN: RDD");
                    NodoArbol<Tarjeta>* Temp = raiz->getHder();
                    (*padre)->setRojicidad(true);
                    Temp->setRojicidad(false);
                    (*padre)->setHizq(Temp->getHder());
                    raiz->setHizq(Temp->getHizq());
                    Temp->setHizq(raiz);
                    Temp->setHder(*padre);
                    *padre=Temp;
                }
            }


    }
    }
}
